#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>

#define SEP " "
#define NUM 1024
#define SIZE 128
char command_line[NUM];
char* command_args[SIZE];
char* env_buff[NUM];

//内建命令
void ChangeDir(char* path)
{
   chdir(path);
}

void PutEnvMyshell(const char* new_env)
{
   putenv(new_env);
}
int main()
{
  //shell是一个死循环
  while(1)
  {
      //1. 显示提示符
      printf("[lzy@主机名 当前目录]# ");
      fflush(stdout);
      //2. 获取用户输入
      memset(command_line,'\0',sizeof(command_line) * sizeof(char));
      fgets(command_line,NUM,stdin); //从键盘中获取字符串
      command_line[strlen(command_line) - 1] = '\0';
      //3. 字符串切割
      command_args[0] = strtok(command_line,SEP);
      int index = 1;
      if(strcmp(command_args[0],"ls") == 0){
        command_args[index++] = "--color=auto";
      }
      while(command_args[index++] = strtok(NULL,SEP));
   //   for(int i = 0; i < index; i++)
   //   {
   //     printf("%s ",command_args[i]);
   //   }
   //   printf("\n");
   //   //4. 编写内建命令 内建命令 --父进程执行、子进程不执行
      if(strcmp(command_args[0],"cd") == 0 && strlen(command_args) > 1){
        ChangeDir(command_args[1]);
        continue;
      }
      if(strcmp(command_args[0],"export") == 0 && strlen(command_args) > 1){
        strcpy(env_buff,command_args[1]);
        PutEnvMyshell(env_buff);
        continue;
      }
      //5. 创建进程、执行
      pid_t id = fork();
      if(id == 0)
      {
        //CHILD
        // 6. 程序替换
        execvp(command_args[0],command_args);
        exit(66);//执行到这一段，表示程序替换失败
        
      }else{
        int status = 0;
        pid_t ret = waitpid(id,&status,0);
        if(ret > 0)
        {
          printf("等待子进程成功 sig: %d,code: %d\n",status&0x3F,(status>>8)&0xFF);
           if(WEXITSTATUS(status) == 66 ){ //非正常退出
              printf("程序替换失败\n");
             }
        }
      }
  }
  return 0;
}
